﻿using System;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Transactions;
using System.Xml;
using System.IO;

namespace Microsoft.Biztalk.Adapters.Wcf.NullBinding
{
    class NullOutputChannel : NullChannelBase, IOutputChannel
    {
        public NullOutputChannel(ChannelManagerBase manager, NullBindingProperties props)
            : base(manager, props)
        {
        }

        public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state)
        {
            Send(message);
            return new NullAsyncResult(callback, state);
        }

        public IAsyncResult BeginSend(Message message, AsyncCallback callback, object state)
        {
            Send(message);
            return new NullAsyncResult(callback, state);
        }

        public void EndSend(IAsyncResult result)
        {
        }

        public EndpointAddress RemoteAddress
        {
            get { return new EndpointAddress(Helpers.Address); }
        }

        public void Send(Message message, TimeSpan timeout)
        {
            Send(message);
        }

        public void Send(Message message)
        {
            Helpers.LogReceivedMessage(message, this.Properties.LogMessages, MessageType.Output);
            CommittableTransaction txn = Transaction.Current as CommittableTransaction;
            if (txn != null)
                txn.Commit();
        }

        public Uri Via
        {
            get { return new Uri(Helpers.Address); }
        }
    }

    class NullRequestChannel : NullChannelBase, IRequestChannel
    {
        public NullRequestChannel(ChannelManagerBase manager, NullBindingProperties props)
            : base(manager, props)
        {
        }

        public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
        {
            Helpers.LogReceivedMessage(message, this.Properties.LogMessages,MessageType.Request);
            return new NullAsyncResult(EvaluateTimeOut(timeout), callback, state);
        }

        public IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state)
        {
            Helpers.LogReceivedMessage(message, this.Properties.LogMessages, MessageType.Request);
            return new NullAsyncResult(EvaluateTimeOut(this.DefaultReceiveTimeout), callback, state);
        }

        public Message EndRequest(IAsyncResult result)
        {
            CommittableTransaction txn = Transaction.Current as CommittableTransaction;
            if (txn != null && txn.TransactionInformation.Status == TransactionStatus.Active)
                txn.Commit();

            Message reply = Message.CreateMessage(MessageVersion.Default, Helpers.Action, (object)this.Properties.MessageBody);
            Helpers.LogCreatedMessage(reply, this.Properties.LogMessages, MessageType.Reply);

            return reply;
        }

        public EndpointAddress RemoteAddress
        {
            get { return new EndpointAddress(Helpers.Address); }
        }

        public Message Request(Message message, TimeSpan timeout)
        {
            return EndRequest(BeginRequest(message, timeout, null, null));
        }

        public Message Request(Message message)
        {
            return EndRequest(BeginRequest(message, null, null));
        }

        public Uri Via
        {
            get { return new Uri(Helpers.Address); }
        }
    }

}
